package com.uniflow.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uniflow.common.PageResult;
import com.uniflow.common.Result;
import com.uniflow.common.ResultCode;
import com.uniflow.entity.Permission;
import com.uniflow.service.PermissionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;

/**
 * 权限管理控制器
 * 
 * @author uniflow
 * @since 1.0.0
 */
@RestController
@RequestMapping("/api/v1/permissions")
@Validated
@Api(tags = "权限管理")
public class PermissionController {
    
    @Autowired
    private PermissionService permissionService;
    
    /**
     * 分页查询权限列表
     */
    @GetMapping
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("分页查询权限列表")
    public Result<PageResult<Permission>> getPermissionList(
            @ApiParam("页码") @RequestParam(defaultValue = "1") int pageNum,
            @ApiParam("页大小") @RequestParam(defaultValue = "10") int pageSize,
            @ApiParam("权限类型") @RequestParam(required = false) String type,
            @ApiParam("父级权限ID") @RequestParam(required = false) String parentId,
            @ApiParam("是否启用") @RequestParam(required = false) Boolean enabled,
            @ApiParam("关键词") @RequestParam(required = false) String keyword) {
        try {
            IPage<Permission> page = permissionService.getPermissionPage(pageNum, pageSize, type, parentId, enabled, keyword);
            PageResult<Permission> result = new PageResult<Permission>(pageNum, pageSize, page.getTotal(), page.getRecords());
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据ID查询权限详情
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("根据ID查询权限详情")
    public Result<Permission> getPermissionById(@ApiParam("权限ID") @PathVariable String id) {
        try {
            Permission permission = permissionService.getPermissionWithHierarchy(id);
            if (permission == null) {
                return Result.error(ResultCode.NOT_FOUND, "权限不存在");
            }
            return Result.success(permission);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据权限代码查询权限
     */
    @GetMapping("/code/{code}")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("根据权限代码查询权限")
    public Result<Permission> getPermissionByCode(@ApiParam("权限代码") @PathVariable String code) {
        try {
            Permission permission = permissionService.getPermissionByCode(code);
            if (permission == null) {
                return Result.error(ResultCode.NOT_FOUND, "权限不存在");
            }
            return Result.success(permission);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询权限树结构
     */
    @GetMapping("/tree")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询权限树结构")
    public Result<List<Permission>> getPermissionTree() {
        try {
            List<Permission> tree = permissionService.getPermissionTree();
            return Result.success(tree);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询菜单权限树
     */
    @GetMapping("/menu-tree")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询菜单权限树")
    public Result<List<Permission>> getMenuPermissionTree() {
        try {
            List<Permission> tree = permissionService.getMenuPermissionTree();
            return Result.success(tree);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询根权限列表
     */
    @GetMapping("/roots")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询根权限列表")
    public Result<List<Permission>> getRootPermissions() {
        try {
            List<Permission> roots = permissionService.getRootPermissions();
            return Result.success(roots);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据父级ID查询子权限
     */
    @GetMapping("/children/{parentId}")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("根据父级ID查询子权限")
    public Result<List<Permission>> getChildrenPermissions(@ApiParam("父级权限ID") @PathVariable String parentId) {
        try {
            List<Permission> children = permissionService.getChildrenPermissions(parentId);
            return Result.success(children);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据类型查询权限
     */
    @GetMapping("/type/{type}")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("根据类型查询权限")
    public Result<List<Permission>> getPermissionsByType(@ApiParam("权限类型") @PathVariable String type) {
        try {
            List<Permission> permissions = permissionService.getPermissionsByType(type);
            return Result.success(permissions);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询用户权限列表
     */
    @GetMapping("/user/{userId}")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询用户权限列表")
    public Result<List<Permission>> getUserPermissions(@ApiParam("用户ID") @PathVariable String userId) {
        try {
            List<Permission> permissions = permissionService.getUserPermissions(userId);
            return Result.success(permissions);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询角色权限列表
     */
    @GetMapping("/role/{roleId}")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询角色权限列表")
    public Result<List<Permission>> getRolePermissions(@ApiParam("角色ID") @PathVariable String roleId) {
        try {
            List<Permission> permissions = permissionService.getRolePermissions(roleId);
            return Result.success(permissions);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 检查用户是否有指定权限
     */
    @GetMapping("/check/user/{userId}/{permissionCode}")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("检查用户是否有指定权限")
    public Result<Boolean> hasUserPermission(
            @ApiParam("用户ID") @PathVariable String userId,
            @ApiParam("权限代码") @PathVariable String permissionCode) {
        try {
            boolean hasPermission = permissionService.hasUserPermission(userId, permissionCode);
            return Result.success(hasPermission);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 检查角色是否有指定权限
     */
    @GetMapping("/check/role/{roleId}/{permissionCode}")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("检查角色是否有指定权限")
    public Result<Boolean> hasRolePermission(
            @ApiParam("角色ID") @PathVariable String roleId,
            @ApiParam("权限代码") @PathVariable String permissionCode) {
        try {
            boolean hasPermission = permissionService.hasRolePermission(roleId, permissionCode);
            return Result.success(hasPermission);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 创建权限
     */
    @PostMapping
    @PreAuthorize("hasAuthority('permission:write')")
    @ApiOperation("创建权限")
    public Result<Permission> createPermission(@Valid @RequestBody CreatePermissionRequest request) {
        try {
            Permission permission = new Permission();
            permission.setCode(request.getCode());
            permission.setName(request.getName());
            permission.setDescription(request.getDescription());
            permission.setType(request.getType());
            permission.setResource(request.getResource());
            permission.setAction(request.getAction());
            permission.setParentId(request.getParentId());
            permission.setSortOrder(request.getSortOrder());
            permission.setEnabled(request.getEnabled());
            
            Permission createdPermission = permissionService.createPermission(permission);
            return Result.success(createdPermission);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 更新权限
     */
    @PutMapping("/{id}")
    @PreAuthorize("hasAuthority('permission:write')")
    @ApiOperation("更新权限")
    public Result<Permission> updatePermission(
            @ApiParam("权限ID") @PathVariable String id,
            @Valid @RequestBody UpdatePermissionRequest request) {
        try {
            Permission permission = new Permission();
            permission.setId(id);
            permission.setCode(request.getCode());
            permission.setName(request.getName());
            permission.setDescription(request.getDescription());
            permission.setType(request.getType());
            permission.setResource(request.getResource());
            permission.setAction(request.getAction());
            permission.setParentId(request.getParentId());
            permission.setSortOrder(request.getSortOrder());
            permission.setEnabled(request.getEnabled());
            
            Permission updatedPermission = permissionService.updatePermission(permission);
            return Result.success(updatedPermission);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 删除权限
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("hasAuthority('permission:write')")
    @ApiOperation("删除权限")
    public Result<Void> deletePermission(@ApiParam("权限ID") @PathVariable String id) {
        try {
            permissionService.deletePermission(id);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 批量删除权限
     */
    @DeleteMapping
    @PreAuthorize("hasAuthority('permission:write')")
    @ApiOperation("批量删除权限")
    public Result<Void> deletePermissions(@RequestBody @NotEmpty List<String> ids) {
        try {
            permissionService.deletePermissions(ids);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 批量更新权限状态
     */
    @PutMapping("/batch/enabled")
    @PreAuthorize("hasAuthority('permission:write')")
    @ApiOperation("批量更新权限状态")
    public Result<Void> batchUpdateEnabled(@RequestBody BatchUpdateEnabledRequest request) {
        try {
            permissionService.batchUpdateEnabled(request.getIds(), request.getEnabled());
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询权限统计信息
     */
    @GetMapping("/stats")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询权限统计信息")
    public Result<Map<String, Object>> getPermissionStats() {
        try {
            Map<String, Object> stats = permissionService.getPermissionStats();
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询权限类型分布
     */
    @GetMapping("/stats/type-distribution")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询权限类型分布")
    public Result<List<Map<String, Object>>> getTypeDistribution() {
        try {
            List<Map<String, Object>> distribution = permissionService.getTypeDistribution();
            return Result.success(distribution);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询权限使用统计
     */
    @GetMapping("/stats/usage")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询权限使用统计")
    public Result<List<Map<String, Object>>> getUsageStats() {
        try {
            List<Map<String, Object>> usage = permissionService.getUsageStats();
            return Result.success(usage);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询最近创建的权限
     */
    @GetMapping("/recent")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询最近创建的权限")
    public Result<List<Permission>> getRecentCreated(
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<Permission> recent = permissionService.getRecentCreated(limit);
            return Result.success(recent);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询未使用的权限
     */
    @GetMapping("/unused")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询未使用的权限")
    public Result<List<Permission>> getUnusedPermissions() {
        try {
            List<Permission> unused = permissionService.getUnusedPermissions();
            return Result.success(unused);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询权限路径
     */
    @GetMapping("/{id}/path")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询权限路径")
    public Result<List<Permission>> getPermissionPath(@ApiParam("权限ID") @PathVariable String id) {
        try {
            List<Permission> path = permissionService.getPermissionPath(id);
            return Result.success(path);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询权限继承关系
     */
    @GetMapping("/{id}/inheritance")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询权限继承关系")
    public Result<List<Map<String, Object>>> getInheritanceRelations(@ApiParam("权限ID") @PathVariable String id) {
        try {
            List<Map<String, Object>> relations = permissionService.getInheritanceRelations(id);
            return Result.success(relations);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询权限冲突检测
     */
    @GetMapping("/conflicts/{userId}")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询权限冲突检测")
    public Result<List<Map<String, Object>>> getConflictPermissions(@ApiParam("用户ID") @PathVariable String userId) {
        try {
            List<Map<String, Object>> conflicts = permissionService.getConflictPermissions(userId);
            return Result.success(conflicts);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询权限审计信息
     */
    @GetMapping("/{id}/audit")
    @PreAuthorize("hasAuthority('permission:read')")
    @ApiOperation("查询权限审计信息")
    public Result<List<Map<String, Object>>> getAuditInfo(
            @ApiParam("权限ID") @PathVariable String id,
            @ApiParam("开始日期") @RequestParam(required = false) String startDate,
            @ApiParam("结束日期") @RequestParam(required = false) String endDate) {
        try {
            List<Map<String, Object>> audit = permissionService.getAuditInfo(id, startDate, endDate);
            return Result.success(audit);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 初始化系统默认权限
     */
    @PostMapping("/init-defaults")
    @PreAuthorize("hasAuthority('permission:write')")
    @ApiOperation("初始化系统默认权限")
    public Result<Void> initDefaultPermissions() {
        try {
            permissionService.initDefaultPermissions();
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    // ==================== 请求数据结构 ====================
    
    public static class CreatePermissionRequest {
        @NotBlank(message = "权限代码不能为空")
        private String code;
        
        @NotBlank(message = "权限名称不能为空")
        private String name;
        
        private String description;
        
        @NotBlank(message = "权限类型不能为空")
        private String type;
        
        private String resource;
        private String action;
        private String parentId;
        private Integer sortOrder = 0;
        private Boolean enabled = true;
        
        // getters and setters
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        public String getResource() { return resource; }
        public void setResource(String resource) { this.resource = resource; }
        public String getAction() { return action; }
        public void setAction(String action) { this.action = action; }
        public String getParentId() { return parentId; }
        public void setParentId(String parentId) { this.parentId = parentId; }
        public Integer getSortOrder() { return sortOrder; }
        public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
        public Boolean getEnabled() { return enabled; }
        public void setEnabled(Boolean enabled) { this.enabled = enabled; }
    }
    
    public static class UpdatePermissionRequest {
        @NotBlank(message = "权限代码不能为空")
        private String code;
        
        @NotBlank(message = "权限名称不能为空")
        private String name;
        
        private String description;
        
        @NotBlank(message = "权限类型不能为空")
        private String type;
        
        private String resource;
        private String action;
        private String parentId;
        private Integer sortOrder;
        private Boolean enabled;
        
        // getters and setters
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        public String getResource() { return resource; }
        public void setResource(String resource) { this.resource = resource; }
        public String getAction() { return action; }
        public void setAction(String action) { this.action = action; }
        public String getParentId() { return parentId; }
        public void setParentId(String parentId) { this.parentId = parentId; }
        public Integer getSortOrder() { return sortOrder; }
        public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
        public Boolean getEnabled() { return enabled; }
        public void setEnabled(Boolean enabled) { this.enabled = enabled; }
    }
    
    public static class BatchUpdateEnabledRequest {
        @NotEmpty(message = "权限ID列表不能为空")
        private List<String> ids;
        
        private Boolean enabled;
        
        // getters and setters
        public List<String> getIds() { return ids; }
        public void setIds(List<String> ids) { this.ids = ids; }
        public Boolean getEnabled() { return enabled; }
        public void setEnabled(Boolean enabled) { this.enabled = enabled; }
    }
}